﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Common;
using System.Xml;

namespace WpfHardCodedStringsFinder.Views
{
	/// <summary>
	/// Interaction logic for CreateResourceFileWindow.xaml
	/// </summary>
	public partial class CreateResourceFileWindow : Window
	{
		private string m_projectPath = string.Empty;
		private string m_rootNamespace = string.Empty;
		private string m_createdFileName = string.Empty;
		private const string xmlNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";

		/// <summary>
		/// Path for newly created resource file
		/// </summary>
		public string CreatedResourceFilePath { get { return m_createdFileName; } }

		public CreateResourceFileWindow()
		{
			InitializeComponent();
		}

		public CreateResourceFileWindow(string projectRoot, string rootNamespace)
		{
			if (string.IsNullOrEmpty(projectRoot))
				throw new ArgumentNullException("projectRoot");

			if (string.IsNullOrEmpty(rootNamespace))
				throw new ArgumentNullException("rootNamespace");

			InitializeComponent();
			m_projectPath = projectRoot;
			m_rootNamespace = rootNamespace;
		}

		public void SetProjectRootPath(string newPath)
		{
			if (!System.IO.Directory.Exists(newPath))
				return;
			m_projectPath = newPath;
		}

		private void btnCreate_Click(object sender, RoutedEventArgs e)
		{
			string tmpResourceFilePath = System.IO.Path.Combine(m_projectPath, "Properties", txtResourceName.Text);

			if (System.IO.File.Exists(tmpResourceFilePath))
			{
				if (MessageBox.Show("This file has already exist \r\n Do you want to replace it?", "", MessageBoxButton.YesNo, MessageBoxImage.Question) ==
					MessageBoxResult.Yes)
				{
					//Create backup of existing file
					if (System.IO.File.Exists(string.Format("{0}.bak", tmpResourceFilePath)))
						System.IO.File.Delete(string.Format("{0}.bak", tmpResourceFilePath));

					System.IO.File.Move(tmpResourceFilePath, string.Format("{0}.bak", tmpResourceFilePath));
				}
				else
				{
					txtResourceName.Text = "Input another file !!!!";
				}
			}

			if (!string.IsNullOrEmpty(txtResourceName.Text) && !System.IO.File.Exists(tmpResourceFilePath) && txtResourceName.Text.Split('.').Length == 2)
			{
				string designerCalssData = string.Empty;
				string resoucesXmlData = string.Empty;
				bool excThrowned = false;
				try
				{
					using (System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("WpfHardCodedStringsFinder.Templates.ResxDesignerClass.txt"))
					{
						if (stream != null)
						{
							using (System.IO.StreamReader sr = new System.IO.StreamReader(stream))
							{
								if (sr.BaseStream.CanSeek)
									sr.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);

								string namesp = string.Format("{0}.Properties", m_rootNamespace);
								designerCalssData = sr.ReadToEnd().Replace("{0}", namesp).Replace("{1}", "Resources");
							}
						}
					}

					using (System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("WpfHardCodedStringsFinder.Templates.ResxTemplate.xml"))
					{
						if (stream != null)
						{
							using (System.IO.StreamReader sr = new System.IO.StreamReader(stream))
							{
								if (sr.BaseStream.CanSeek)
									sr.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);

								resoucesXmlData = sr.ReadToEnd();
							}
						}
					}

					//write resource template to Properties folder in selected project
					using (var resxWriter = new System.IO.StreamWriter(tmpResourceFilePath))
					{
						resxWriter.WriteLine(resoucesXmlData);
					}

					//Name of designer file wich created along with *.resx file
					string designerFileName = string.Format("{0}.Designer.cs", System.IO.Path.GetFileNameWithoutExtension(txtResourceName.Text));

					using (var desWriter = new System.IO.StreamWriter(System.IO.Path.Combine(m_projectPath, "Properties",
						designerFileName)))
					{
						desWriter.WriteLine(designerCalssData);
					}

					var projectFiles = from file in System.IO.Directory.EnumerateFiles(m_projectPath)
									   where
										   System.IO.Path.GetExtension(file) == ".csproj"
									   select file;
					if (projectFiles.Count() == 0)
						throw new InvalidOperationException(string.Format("Cannot locate project file in folder {0}", m_projectPath));

					var xmlDoc = new System.Xml.XmlDocument();
					System.Xml.XmlNamespaceManager xnmgr = new System.Xml.XmlNamespaceManager(new System.Xml.NameTable());
					xnmgr.AddNamespace("prj", xmlNamespace);
					string projectFilePath = projectFiles.First();
					xmlDoc.Load(projectFilePath);
					xnmgr.LookupPrefix("prj");
					int index = xmlDoc.GetIndexOfItemGroupForProperties(xnmgr);

					XmlElement newItemGroup = xmlDoc.CreateElement("ItemGroup", xmlNamespace);

					//Create compile element with all subnodes
					XmlElement compElement = xmlDoc.CreateElement("Compile", xmlNamespace);

					XmlAttribute incAttr = xmlDoc.CreateAttribute("Include");
					incAttr.Value = string.Format(@"Properties\{0}", designerFileName);
					compElement.Attributes.Append(incAttr);
					XmlElement autogenElement = xmlDoc.CreateElement("AutoGen", xmlNamespace);
					autogenElement.InnerText = "True";
					XmlElement designElement = xmlDoc.CreateElement("DesignTime", xmlNamespace);
					designElement.InnerText = "True";
					XmlElement dependentElement = xmlDoc.CreateElement("DependentUpon", xmlNamespace);
					dependentElement.InnerText = txtResourceName.Text.Trim();
					compElement.AppendChild(autogenElement);
					compElement.AppendChild(designElement);
					compElement.AppendChild(dependentElement);

					//Create EmbeddedResource element with all subnodes
					XmlElement embededElement = xmlDoc.CreateElement("EmbeddedResource", xmlNamespace);

					XmlAttribute incAttr2 = xmlDoc.CreateAttribute("Include");
					incAttr2.Value = string.Format(@"Properties\{0}", txtResourceName.Text.Trim());
					embededElement.Attributes.Append(incAttr2);
					XmlElement genElement = xmlDoc.CreateElement("Generator", xmlNamespace);
					genElement.InnerText = "ResXFileCodeGenerator";
					XmlElement lastGenOutElement = xmlDoc.CreateElement("LastGenOutput", xmlNamespace);
					lastGenOutElement.InnerText = designerFileName;
					embededElement.AppendChild(genElement);
					embededElement.AppendChild(lastGenOutElement);

					newItemGroup.AppendChild(compElement);
					newItemGroup.AppendChild(embededElement);

					//Append newly created node to our projectd document
					xmlDoc.DocumentElement.AppendChild(newItemGroup);

					Common.FileUtility.MakeFileWritable(projectFilePath);
					System.IO.File.Delete(projectFilePath);
					xmlDoc.Save(projectFilePath);

					m_createdFileName = System.IO.Path.Combine(m_projectPath, "Properties", txtResourceName.Text.Trim());
				}
				catch (Exception ex)
				{
					excThrowned = true;
					MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
				}
				finally
				{
					if (!excThrowned)
						MessageBox.Show("Resource file created successfully", "", MessageBoxButton.OK, MessageBoxImage.Information);
				}
				this.DialogResult = true;
				this.Close();
			}
		}

		private void btnCancel_Click(object sender, RoutedEventArgs e)
		{
			this.DialogResult = false;
			this.Close();
		}
	}
}
